package com.tywj.lib.net.retrofit.request


import com.tywj.lib.core.common.util.JsonUtil
import com.tywj.lib.net.retrofit.HttpUtil
import com.tywj.lib.net.retrofit.callback.BaseCallback
import com.tywj.lib.net.retrofit.model.ProgressRequestBody
import io.reactivex.Observable
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.ResponseBody
import org.jetbrains.anko.collections.forEachByIndex
import org.json.JSONArray
import org.json.JSONObject
import org.json.JSONTokener
import retrofit2.Response
import java.io.File

/**
 * <pre>
 *     author : June Yang
 *     time   : 2020/5/8
 *     desc   : POST请求
 *     version: 1.0.0
 * </pre>
 * @param isJson 数据类型是否为json，默认是false
 */
class PostRequest(url: String, private val isJson: Boolean = false) :
    BaseRequest<PostRequest>(url) {
    private val jsonObj = JSONObject()
    private var fileParts = ArrayList<MultipartBody.Part>()

    override fun param(key: String, value: String): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: Boolean): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: Int): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: Long): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: Float): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: Double): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: JSONObject): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: JSONArray): PostRequest {
        jsonObj.put(key, value)
        return this
    }

    fun param(key: String, value: Collection<*>): PostRequest {
        jsonObj.put(key, JSONArray(JSONTokener(JsonUtil.toJson(value))))
        return this
    }

    fun param(key: String, value: File): PostRequest {
        if (isJson) {
            throw IllegalArgumentException("Content-Type is application/json, param can not be file!")
        }
        fileParts.add(MultipartBody.Part.createFormData(key, value.name, toRequestBody(value)))

        return this
    }

    //POST中四几种方式
    fun param(key: String, value: List<File>): PostRequest {
        //1. application/json
        if (isJson) {
            throw IllegalArgumentException("Content-Type is application/json, param can not be file!")
        }
        //2.multipart/form-data
        for (item in value) {
            fileParts.add(MultipartBody.Part.createFormData(key, item.name, toRequestBody(item)))
        }

        return this
    }

    override fun getRequestMethod(callback: BaseCallback<*>?): Observable<Response<ResponseBody>> {
        return if (isJson) {
            val body = RequestBody.create(MEDIA_TYPE_JSON, jsonObj.toString())
            HttpUtil.httpConfig.httpMethod.post(url, headers, ProgressRequestBody(body, callback))
        } else {
            val builder = MultipartBody.Builder()
            if (jsonObj.length() + fileParts.size == 0) {
                // 如果没有一个表单项都没有，则增加一个空字符串表单项
                builder.addFormDataPart("", "")
            } else {
                val keys = jsonObj.keys()
                for (key in keys) {
                    builder.addFormDataPart(key, jsonObj.get(key).toString())
                }
                fileParts.forEachByIndex { builder.addPart(it) }
            }

            val body = builder.setType(MultipartBody.FORM).build()
            builder.setType(MultipartBody.FORM)
            HttpUtil.httpConfig.httpMethod.post(url, headers, ProgressRequestBody(body, callback))
        }
    }
}